package com.parking.mgr.useraccount.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.parking.mgr.common.enums.CommonStatusEnum;
import com.parking.mgr.common.exception.ServiceException;
import com.parking.mgr.common.exception.enums.AuthExceptionEnum;
import com.parking.mgr.common.util.IdUtils;
import com.parking.mgr.common.util.MD5Util;
import com.parking.mgr.common.util.PwdCheckUtil;
import com.parking.mgr.useraccount.enums.UserExceptionEnum;
import com.parking.mgr.useraccount.facede.LoginServiceFacede;
import com.parking.mgr.useraccount.facede.UserServiceFacede;
import com.parking.mgr.useraccount.model.entity.LoginPasswordEntity;
import com.parking.mgr.useraccount.model.entity.UserInfoEntity;
import com.parking.mgr.useraccount.model.mapper.LoginPasswordMapper;
import com.parking.mgr.useraccount.model.param.ChangePasswordParam;
import com.parking.mgr.useraccount.model.param.ChangePasswordSelfParam;
import com.parking.mgr.useraccount.model.param.LoginPasswordParam;
import com.parking.mgr.useraccount.model.param.LoginPasswordSelfParam;
import com.parking.mgr.useraccount.service.LoginPasswordService;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import static com.parking.mgr.common.context.constant.ConstantContextHolder.getSysConfigWithDefault;

/**
 * @ClassName LoginPasswordServiceImpl
 * @Description 用户登录密码
 * @Auther: zhijianpu
 * @Date: 2023/5/25
 */
@Log4j2
@Service
public class LoginPasswordServiceImpl extends ServiceImpl<LoginPasswordMapper, LoginPasswordEntity> implements LoginPasswordService {

    @Resource
    private LoginServiceFacede loginServiceFacede;

    @Resource
    private UserServiceFacede userServiceFacede;

    @Resource
    private LoginPasswordMapper loginPasswordMapper;


    @Override
    public void addPasswordSelf(LoginPasswordSelfParam loginPasswordSelfParam, HttpServletRequest request) {
        String passportId = loginServiceFacede.getPassportIdByToken(request);
        this.savePwd(loginPasswordSelfParam.getFPassword(), passportId);
    }

    @Override
    public void addPassword(LoginPasswordParam loginPasswordParam, HttpServletRequest request) {
        String userInfoId = loginPasswordParam.getId();
        UserInfoEntity userInfoEntity = userServiceFacede.getUserInfoById(userInfoId);
        String passportId = userInfoEntity.getFkUserPassportId();

        this.savePwd(loginPasswordParam.getFPassword(), passportId);

    }

    @Override
    public void changePasswordSelf(ChangePasswordSelfParam changePasswordSelfParam, HttpServletRequest request) {
        String passportId = loginServiceFacede.getPassportIdByToken(request);
        this.changePwd(passportId, changePasswordSelfParam.getFPassword(), changePasswordSelfParam.getNewPassword());

    }

    @Override
    public void changePassword(ChangePasswordParam changePasswordParam, HttpServletRequest request) {
        String userInfoId = changePasswordParam.getId();
        UserInfoEntity userInfoEntity = userServiceFacede.getUserInfoById(userInfoId);
        String passportId = userInfoEntity.getFkUserPassportId();

        this.changePwd(passportId, changePasswordParam.getFPassword(), changePasswordParam.getNewPassword());
    }

    @Override
    public void deletePasswordByPassportId(String passportId) {
        loginPasswordMapper.delete(new LambdaQueryWrapper<LoginPasswordEntity>()
                .eq(LoginPasswordEntity::getFkUserPassportId, passportId));
    }


    @Override
    public void savePwd(String password, String passportId) {
        boolean isPwdRegex = PwdCheckUtil.isValidPassword(password);
        if (!isPwdRegex) {
            throw new ServiceException(AuthExceptionEnum.PWD_REGEX_ERROR.getMessage());
        }
        String salt = IdUtils.getSimpleId();
        String md5PwdWithSalt = MD5Util.password(password, salt);

        LoginPasswordEntity loginPasswordEntity = loginPasswordMapper.selectOne(new LambdaQueryWrapper<LoginPasswordEntity>()
                .eq(LoginPasswordEntity::getFkUserPassportId, passportId)
                .ne(LoginPasswordEntity::getFEnableState, CommonStatusEnum.DISABLE.getCode()));

        if (ObjectUtil.isNotNull(loginPasswordEntity)) {
            log.info("更新用户密码");
            loginPasswordEntity.setFPassword(md5PwdWithSalt);
            loginPasswordEntity.setFPasssalt(salt);
            this.updateById(loginPasswordEntity);
        } else {
            log.info("添加用户密码");
            LoginPasswordEntity newLoginPasswordEntity = new LoginPasswordEntity();
            newLoginPasswordEntity.setFPassword(md5PwdWithSalt);
            newLoginPasswordEntity.setFkUserPassportId(passportId);
            newLoginPasswordEntity.setFPasssalt(salt);
            newLoginPasswordEntity.setId(IdUtils.getId());

            this.save(newLoginPasswordEntity);
        }

    }

    private void changePwd(String passportId, String inputOldPwd, String newPwd) {
        LoginPasswordEntity loginPasswordEntity = loginPasswordMapper.selectOne(new LambdaQueryWrapper<LoginPasswordEntity>()
                .eq(LoginPasswordEntity::getFkUserPassportId, passportId)
                .ne(LoginPasswordEntity::getFEnableState, CommonStatusEnum.DISABLE.getCode()));


        if (ObjectUtil.isNotNull(loginPasswordEntity)) {
            log.info("更新登录用户密码");
            String salt = loginPasswordEntity.getFPasssalt();
            String dbPwd = loginPasswordEntity.getFPassword();

            // 是否需要校验新密码和原密码相同
            boolean isCheckPwd = getSysConfigWithDefault("CHECK_OLDPWD_NEWPWD", Boolean.class, false);
            if (isCheckPwd) {
                if (!MD5Util.compare(newPwd, salt, dbPwd)) {
                    throw new ServiceException(UserExceptionEnum.USER_PWD_REPEAT);
                }
            }

            // 原密码错误
            if (!MD5Util.compare(inputOldPwd, salt, dbPwd)) {
                throw new ServiceException(UserExceptionEnum.USER_PWD_ERROR);
            }

            loginPasswordEntity.setFPassword(MD5Util.password(newPwd, salt));
            this.updateById(loginPasswordEntity);
        } else {
            log.info("添加登录用户密码");
            // 添加密码
            boolean isPwdRegex = PwdCheckUtil.isValidPassword(newPwd);
            if (!isPwdRegex) {
                throw new ServiceException(AuthExceptionEnum.PWD_REGEX_ERROR.getMessage());
            }
            String salt = IdUtils.getSimpleId();
            String md5PwdWithSalt = MD5Util.password(newPwd, salt);

            LoginPasswordEntity newLoginPasswordEntity = new LoginPasswordEntity();
            newLoginPasswordEntity.setFPassword(md5PwdWithSalt);
            newLoginPasswordEntity.setFkUserPassportId(passportId);
            newLoginPasswordEntity.setFPasssalt(salt);
            newLoginPasswordEntity.setId(IdUtils.getId());

            this.save(newLoginPasswordEntity);
        }


    }

}
